const isProperty = (key) => key !== 'children'

export function createElement(type, props) {
  if (typeof type === 'function') {
    return type(props)
  } else if (typeof type === 'string') {
    return {
      type,
      props: {
        ...props,
        children: getChildren(props.children),
      },
    }
  } else {
    throw new Error('type should be function or string')
  }
}

export function render(element, container) {
  let dom
  if (element.type == 'TEXT_ELEMENT') {
    dom = container.txt(element.props.nodeValue)
  } else {
    dom = container.ele(element.type)
    Object.keys(element.props)
      .filter(isProperty)
      .forEach((name) => {
        dom.att(name, element.props[name])
      })
  }
  element.props.children.forEach((child) => render(child, dom))
}

export function Fragment({ children }) {
  return children
}

function getChildren(children) {
  if (typeof children === 'number' || typeof children === 'string') {
    return [createTextElement(children)]
  } else if (children instanceof Array) {
    return children
      .map((child) =>
        typeof child === 'object' ? child : createTextElement(child)
      )
      .flat() // flat用于展平fragment
  } else if (typeof children === 'undefined') {
    return []
  } else {
    return [children]
  }
}

function createTextElement(text) {
  return {
    type: 'TEXT_ELEMENT',
    props: {
      nodeValue: text,
      children: [],
    },
  }
}
